package com.rongmei.jdsync.controller;

import com.rongmei.jdsync.dto.*;
import com.rongmei.jdsync.entity.Category;
import com.rongmei.jdsync.entity.Goods;
import com.rongmei.jdsync.entity.SkuData;
import com.rongmei.jdsync.response.ApiResponse;
import com.rongmei.jdsync.service.GoodsService;
import com.rongmei.jdsync.service.JdCategorySyncService;
import com.rongmei.jdsync.service.SkuDataService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.ResponseEntity;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

import org.springframework.beans.BeanUtils;

/**
 * @author dongjun
 */
@Tag(name = "京东商品分类同步API")
@RestController
@RequestMapping("/api/jd/category")
@Slf4j
public class JdCategorySyncController {

    private final JdCategorySyncService jdCategorySyncService;
    private final GoodsService goodsService;
    private final SkuDataService skuDataService;

    public JdCategorySyncController(JdCategorySyncService jdCategorySyncService, GoodsService goodsService, SkuDataService skuDataService) {
        this.jdCategorySyncService = jdCategorySyncService;
        this.goodsService = goodsService;
        this.skuDataService = skuDataService;
    }

    /**
     * 导出商品图片接口
     * 该接口用于将商品图片从URL下载到本地指定目录
     *
     * @return 如果导出成功，返回包含"导出成功"信息的ResponseEntity；如果导出失败，返回包含错误信息的ResponseEntity
     */
    @Operation(summary = "导出商品图片", description = "将商品图片从URL下载到本地指定目录")
    @PostMapping("/goods/export-images")
    public ResponseEntity<?> exportGoodsImages() {
        try {
            goodsService.downloadGoodsImages();
            return ResponseEntity.ok().body(ApiResponse.success("导出任务已启动"));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "导出失败: " + e.getMessage()));
        }
    }

    /**
     * 同步京东商品分类数据接口
     * 该接口用于从京东API同步商品分类数据到本地数据库，支持根据分类名称进行同步。
     *
     * @param categoryName 商品分类名称，非必填参数。若提供，则只同步指定分类的数据；若不提供，则同步所有分类数据。
     * @return 如果同步成功，返回包含同步结果数量的ResponseEntity；如果同步失败，返回包含错误信息的ResponseEntity。
     */
    @Operation(summary = "同步京东商品分类数据", description = "从京东API同步商品分类数据到本地数据库")
    @PostMapping("/sync")
    public ResponseEntity<?> syncCategories(
            @RequestParam(name = "categoryName", required = false) String categoryName) {
        try {
            JdCategoryResponseDto result = jdCategorySyncService.syncCategories(categoryName);
            return ResponseEntity.ok()
                    .body(ApiResponse.success(result.getData() != null ? result.getData().size() : 0));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "同步失败: " + e.getMessage()));
        }
    }

    /**
     * 保存京东商品分类数据接口
     * 该接口用于将京东API返回的商品分类数据保存到本地数据库，并先获取并保存商品标签数据。
     *
     * @param responseDto 京东API返回的商品分类数据
     * @return 如果保存成功，返回包含"保存成功"信息的ResponseEntity；如果保存失败，返回包含错误信息的ResponseEntity
     */

    @Operation(summary = "保存京东商品分组数据到", description = "将京东API返回的分组据保存到本地数据库")
    @PostMapping("/save")
    public ResponseEntity<?> saveCategories(@RequestBody JdCategoryResponseDto responseDto) {
        try {
            JdLabelResponseDto labelResponseDto = jdCategorySyncService.getLabelList();
            jdCategorySyncService.saveLabelList(labelResponseDto);
            return ResponseEntity.ok().body(ApiResponse.success("保存成功"));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "保存失败: " + e.getMessage()));
        }
    }

    @Operation(summary = "获取京东商品列表", description = "从京东API获取商品列表数据")
    @PostMapping("/goods/list")
    public ResponseEntity<?> getGoodsList(@RequestBody GoodsRequestDto requestDto) {
        ExecutorService executor = Executors.newFixedThreadPool(8);
        try {
            AtomicBoolean shouldContinue = new AtomicBoolean(true);
            AtomicInteger currentPage = new AtomicInteger(requestDto.getPage());

            while (shouldContinue.get()) {
                // 提交8个任务作为一个批次
                List<Future<?>> batchFutures = new ArrayList<>(8);
                for (int i = 0; i < 8 && shouldContinue.get(); i++) {
                    final int page = currentPage.getAndIncrement();
                    Future<?> future = executor.submit(() -> {
                        try {
                            GoodsRequestDto pageRequest = new GoodsRequestDto();
                            BeanUtils.copyProperties(requestDto, pageRequest);
                            pageRequest.setPage(page);

                            JdGoodsResponseDto dto = jdCategorySyncService.getGoodsList(pageRequest);
                            if (!dto.isSuccess() || dto.getData().getList().isEmpty()) {
                                shouldContinue.set(false);
                            }
                        } catch (Exception e) {
                            log.error("Failed to get JD goods list for page {}, error={}", page, e.getMessage());
                        }
                    });
                    batchFutures.add(future);
                }

                // 等待当前批次所有任务完成
                for (Future<?> future : batchFutures) {
                    try {
                        future.get();
                    } catch (Exception e) {
                        log.error("Error waiting for task completion", e);
                    }
                }

                // 批次完成后休眠10秒
                if (shouldContinue.get() && !batchFutures.isEmpty()) {
                    try {
                        log.info("已完成8次请求批次，休眠10秒");
                        TimeUnit.SECONDS.sleep(5);
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        shouldContinue.set(false);
                    }
                }
            }

            return ResponseEntity.ok().body(ApiResponse.success("成功"));

        } catch (Exception e) {
            log.error("Failed to get JD goods list, error={}", e.getMessage());
            return ResponseEntity.badRequest().body(ApiResponse.error(500, e.getMessage()));
        } finally {
            executor.shutdown();
            try {
                if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                    executor.shutdownNow();
                }
            } catch (InterruptedException e) {
                executor.shutdownNow();
                Thread.currentThread().interrupt();
            }
        }
    }


    /**
     * 获取京东商品详情接口
     * 该接口用于从京东API获取商品详情数据
     *
     * @return 如果获取成功，返回包含商品详情数据的ResponseEntity；如果获取失败，返回包含错误信息的ResponseEntity
     */
    @Operation(summary = "获取京东商品详情", description = "从京东API获取商品详情数据")
    @GetMapping("/goods/detail")
    public ResponseEntity<?> getGoodsDetail() {
        try {

            List<Goods> goodsList = goodsService.findGoodsAll();
            goodsList.forEach(goods -> {
                try {
                    GoodsDetailInfoResponseDto dto = jdCategorySyncService
                            .getGoodsDetailInfo(String.valueOf(goods.getGoodsId()), "", "");
                    if (dto != null && dto.getData() != null) {
                        jdCategorySyncService.saveGoodsDetail(dto.getData());
                    }

                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            });

            return ResponseEntity.ok().body(ApiResponse.success("成功"));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "获取商品详情失败: " + e.getMessage()));
        }
    }

    /**
     * 获取商品分类列表接口
     * 该接口用于获取指定分类ID的子分类列表，如果不提供分类ID，则返回所有一级分类
     *
     * @param categoryId 分类ID，非必填参数。若提供，则返回该分类的子分类；若不提供，则返回所有一级分类。
     * @return 如果获取成功，返回包含分类列表的ResponseEntity；如果获取失败，返回包含错误信息的ResponseEntity。
     */
    @Operation(summary = "获取商品分类列表", description = "获取指定分类ID的子分类列表，不提供分类ID则返回所有一级分类")
    @GetMapping("/list")
    public ResponseEntity<?> getCategoryList(
            @RequestParam(name = "categoryId", required = false) Long categoryId) {
        try {
            List<Category> categories = jdCategorySyncService.getCategoryList(categoryId);
            return ResponseEntity.ok()
                    .body(ApiResponse.success(categories));
        } catch (Exception e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "获取分类列表失败: " + e.getMessage()));
        }
    }

    /**
     * 导出商品分类Excel接口
     *
     * @return 文件下载响应
     */
    @Operation(summary = "导出商品分类Excel", description = "导出商品分类数据到Excel文件")
    @GetMapping("/export-excel")
    public ResponseEntity<?> exportCategoryExcel() {
        try {
            byte[] excelBytes = goodsService.exportCategoryToExcel();

            return ResponseEntity.ok()
                    .header("Content-Disposition", "attachment; filename=category_export.xlsx")
                    .header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
                    .body(excelBytes);
        } catch (IOException e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "导出Excel失败: " + e.getMessage()));
        }
    }

    @Operation(summary = "导出商品Excel", description = "导出所有商品数据到Excel文件")
    @GetMapping("/goods/export-excel")
    public ResponseEntity<?> exportGoodsExcel() {
        try {
            byte[] excelBytes = goodsService.exportGoodsToExcel();

            return ResponseEntity.ok()
                    .header("Content-Disposition", "attachment; filename=goods_export.xlsx")
                    .header("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
                    .body(excelBytes);
        } catch (IOException e) {
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "导出Excel失败: " + e.getMessage()));
        }
    }


    @Operation(summary = "获取京东SKU数据", description = "从京东API获取SKU数据")
    @GetMapping("/goods/sku-data")
    @Transactional
    public ResponseEntity<?> getGoodsSkuData() {
        try {
            List<Goods> goodsList = goodsService.findGoodsAll();
            int successCount = 0;
            int failCount = 0;

            for (Goods goods : goodsList) {
                Long goodsId = goods.getGoodsId();
                log.info("开始处理商品ID: {} 的SKU数据", goodsId);

                try {
                    GoodsDetailInfoResponseDto dto = jdCategorySyncService.getGoodsDetailInfo(String.valueOf(goodsId), "", "");
                    if (dto == null || dto.getData() == null || dto.getData().getSkuData().isEmpty()) {
                        log.warn("商品ID: {} 无SKU数据", goodsId);
                        failCount++;
                        continue;
                    }

                    List<SkuData> skuDataList = dto.getData().getSkuData().stream()
                        .map(skuDto -> {
                            SkuData skuData = new SkuData();
                            skuData.setGoodsId(goodsId);
                            skuData.setSkuId(skuDto.getSkuId());
                            skuData.setSkuName(skuDto.getSkuName());
                            skuData.setSkuImage(skuDto.getSkuImage());
                            skuData.setPrice(skuDto.getPrice());
                            skuData.setMarketPrice(skuDto.getMarketPrice());
                            skuData.setCostPrice(skuDto.getCostPrice());
                            skuData.setStock(skuDto.getStock());
                            skuData.setWeight(skuDto.getWeight());
                            skuData.setVolume(skuDto.getVolume());
                            skuData.setGoodsState(1);
                            return skuData;
                        }).collect(Collectors.toList());

                    skuDataService.saveAll(skuDataList);
                    successCount++;
                    log.info("商品ID: {} SKU数据保存成功，共{}条", goodsId, skuDataList.size());
                } catch (NumberFormatException e) {
                    log.error("商品ID: {} 格式错误", goodsId, e);
                    failCount++;
                } catch (IOException e) {
                    log.error("商品ID: {} 获取SKU数据失败", goodsId, e);
                    failCount++;
                }
            }

            String msg = String.format("SKU数据处理完成，成功%d个，失败%d个", successCount, failCount);
            return ResponseEntity.ok().body(ApiResponse.success(msg));
        } catch (Exception e) {
            log.error("获取商品SKU数据异常", e);
            return ResponseEntity.badRequest().body(ApiResponse.error(400, "获取商品SKU数据失败: " + e.getMessage()));
        }
    }







}
